home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / doom / quake_ad.zip / HIPQW.ZIP / SRC / CLIENT.QC < prev    next >
Text File  |  1997-03-14  |  36KB  |  1,595 lines

  1.  
  2. // prototypes
  3. void () W_WeaponFrame;
  4. void() W_SetCurrentAmmo;
  5. void() player_pain;
  6. void() player_stand1;
  7. void (vector org) spawn_tfog;
  8. void (vector org, entity death_owner) spawn_tdeath;
  9.  
  10. float    modelindex_eyes, modelindex_player, 
  11. //hip
  12. modelindex_hammer;
  13. //hip
  14. /*
  15. =============================================================================
  16.  
  17.                 LEVEL CHANGING / INTERMISSION
  18.  
  19. =============================================================================
  20. */
  21.  
  22. string nextmap;
  23.  
  24. float    intermission_running;
  25. float    intermission_exittime;
  26.  
  27. /*QUAKED info_intermission (1 0.5 0.5) (-16 -16 -16) (16 16 16)
  28. This is the camera point for the intermission.
  29. Use mangle instead of angle, so you can set pitch or roll as well as yaw.  'pitch roll yaw'
  30. */
  31. void() info_intermission =
  32. {
  33. };
  34.  
  35.  
  36.  
  37. void() SetChangeParms =
  38. {
  39.     if (self.health <= 0)
  40.      {
  41.          SetNewParms ();
  42.          return;
  43.      }
  44.  
  45. // remove items
  46.     self.items = self.items - (self.items & 
  47.     (IT_KEY1 | IT_KEY2 | IT_INVISIBILITY | IT_INVULNERABILITY | IT_SUIT | IT_QUAD) );
  48.  
  49. //hip
  50.    self.items2 = self.items2 - (self.items2 &
  51.    (HIP_IT_WETSUIT | HIP_IT_EMPATHY_SHIELDS ) );
  52.    self.gravity = 1.0;
  53. //hip
  54.  
  55.     
  56. // cap super health
  57.     if (self.health > 100)
  58.         self.health = 100;
  59.     if (self.health < 50)
  60.         self.health = 50;
  61.     parm1 = self.items;
  62.     parm2 = self.health;
  63.     parm3 = self.armorvalue;
  64.     if (self.ammo_shells < 25)
  65.         parm4 = 25;
  66.     else
  67.         parm4 = self.ammo_shells;
  68.     parm5 = self.ammo_nails;
  69.     parm6 = self.ammo_rockets;
  70.     parm7 = self.ammo_cells;
  71.     parm8 = self.weapon;
  72.     parm9 = self.armortype * 100;
  73. };
  74.  
  75. void() SetNewParms =
  76. {
  77.     parm1 = IT_SHOTGUN | IT_AXE;
  78.     parm2 = 100;
  79.     parm3 = 0;
  80.     parm4 = 25;
  81.     parm5 = 0;
  82.     parm6 = 0;
  83.     parm7 = 0;
  84.     parm8 = 1;
  85.     parm9 = 0;
  86. };
  87.  
  88. void() DecodeLevelParms =
  89. {
  90.     if (serverflags)
  91.     {
  92.         if (world.model == "maps/start.bsp")
  93.             SetNewParms ();        // take away all stuff on starting new episode
  94.     }
  95.     
  96.     self.items = parm1;
  97.     self.health = parm2;
  98.     self.armorvalue = parm3;
  99.     self.ammo_shells = parm4;
  100.     self.ammo_nails = parm5;
  101.     self.ammo_rockets = parm6;
  102.     self.ammo_cells = parm7;
  103.     self.weapon = parm8;
  104.     self.armortype = parm9 * 0.01;
  105. };
  106.  
  107. /*
  108. ============
  109. FindIntermission
  110.  
  111. Returns the entity to view from
  112. ============
  113. */
  114. entity() FindIntermission =
  115. {
  116.     local    entity spot;
  117.     local    float cyc;
  118.  
  119. // look for info_intermission first
  120.     spot = find (world, classname, "info_intermission");
  121.     if (spot)
  122.     {    // pick a random one
  123.         cyc = random() * 4;
  124.         while (cyc > 1)
  125.         {
  126.             spot = find (spot, classname, "info_intermission");
  127.             if (!spot)
  128.                 spot = find (spot, classname, "info_intermission");
  129.             cyc = cyc - 1;
  130.         }
  131.         return spot;
  132.     }
  133.  
  134. // then look for the start position
  135.     spot = find (world, classname, "info_player_start");
  136.     if (spot)
  137.         return spot;
  138.     
  139.     objerror ("FindIntermission: no spot");
  140. };
  141.  
  142.  
  143. void() GotoNextMap =
  144. {
  145. //ZOID: 12-13-96, samelevel is overloaded, only 1 works for same level
  146.     if (cvar("samelevel") == 1)    // if samelevel is set, stay on same level
  147.         changelevel (mapname);
  148.     else
  149.         changelevel (nextmap);
  150. };
  151.  
  152.  
  153.  
  154. /*
  155. ============
  156. IntermissionThink
  157.  
  158. When the player presses attack or jump, change to the next level
  159. ============
  160. */
  161. void() IntermissionThink =
  162. {
  163.     if (time < intermission_exittime)
  164.         return;
  165.  
  166.     if (!self.button0 && !self.button1 && !self.button2)
  167.         return;
  168.     
  169.     GotoNextMap ();
  170. };
  171.  
  172. /*
  173. ============
  174. execute_changelevel
  175.  
  176. The global "nextmap" has been set previously.
  177. Take the players to the intermission spot
  178. ============
  179. */
  180. void() execute_changelevel =
  181. {
  182.     local entity    pos;
  183.  
  184.     intermission_running = 1;
  185.     
  186. // enforce a wait time before allowing changelevel
  187.     intermission_exittime = time + 5;
  188.  
  189.     pos = FindIntermission ();
  190.  
  191. // play intermission music
  192.     WriteByte (MSG_ALL, SVC_CDTRACK);
  193.     WriteByte (MSG_ALL, 3);
  194.  
  195.     WriteByte (MSG_ALL, SVC_INTERMISSION);
  196.     WriteCoord (MSG_ALL, pos.origin_x);
  197.     WriteCoord (MSG_ALL, pos.origin_y);
  198.     WriteCoord (MSG_ALL, pos.origin_z);
  199.     WriteAngle (MSG_ALL, pos.mangle_x);
  200.     WriteAngle (MSG_ALL, pos.mangle_y);
  201.     WriteAngle (MSG_ALL, pos.mangle_z);
  202.     
  203.     other = find (world, classname, "player");
  204.     while (other != world)
  205.     {
  206.         other.takedamage = DAMAGE_NO;
  207.         other.solid = SOLID_NOT;
  208.         other.movetype = MOVETYPE_NONE;
  209.         other.modelindex = 0;
  210.         other = find (other, classname, "player");
  211.     }    
  212.  
  213. };
  214.  
  215.  
  216. void() changelevel_touch =
  217. {
  218.     local entity    pos;
  219.  
  220.     if (other.classname != "player")
  221.         return;
  222.  
  223. // if "noexit" is set, blow up the player trying to leave
  224. //ZOID, 12-13-96, noexit isn't supported in QW.  Overload samelevel
  225. //    if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) && (mapname != "start")))
  226.     if ((cvar("samelevel") == 2) || ((cvar("samelevel") == 3) && (mapname != "start")))
  227.     {
  228.         T_Damage (other, self, self, 50000);
  229.         return;
  230.     }
  231.  
  232.     bprint (PRINT_HIGH, other.netname);
  233.     bprint (PRINT_HIGH," exited the level\n");
  234.     
  235.     nextmap = self.map;
  236.  
  237.     SUB_UseTargets ();
  238.  
  239.     self.touch = SUB_Null;
  240.  
  241. // we can't move people right now, because touch functions are called
  242. // in the middle of C movement code, so set a think time to do it
  243.     self.think = execute_changelevel;
  244.     self.nextthink = time + 0.1;
  245. };
  246.  
  247. /*QUAKED trigger_changelevel (0.5 0.5 0.5) ? NO_INTERMISSION
  248. When the player touches this, he gets sent to the map listed in the "map" variable.  Unless the NO_INTERMISSION flag is set, the view will go to the info_intermission spot and display stats.
  249. */
  250. void() trigger_changelevel =
  251. {
  252.     if (!self.map)
  253.         objerror ("chagnelevel trigger doesn't have map");
  254.     
  255.     InitTrigger ();
  256.     self.touch = changelevel_touch;
  257. };
  258.  
  259.  
  260. /*
  261. =============================================================================
  262.  
  263.                 PLAYER GAME EDGE FUNCTIONS
  264.  
  265. =============================================================================
  266. */
  267.  
  268. void() set_suicide_frame;
  269.  
  270. // called by ClientKill and DeadThink
  271. void() respawn =
  272. {
  273.     // make a copy of the dead body for appearances sake
  274.     CopyToBodyQue (self);
  275.     // set default spawn parms
  276.     SetNewParms ();
  277.     // respawn        
  278.     PutClientInServer ();
  279. };
  280.  
  281.  
  282. /*
  283. ============
  284. ClientKill
  285.  
  286. Player entered the suicide command
  287. ============
  288. */
  289. void() ClientKill =
  290. {
  291.     bprint (PRINT_MEDIUM, self.netname);
  292.     bprint (PRINT_MEDIUM, " suicides\n");
  293.     set_suicide_frame ();
  294.     self.modelindex = modelindex_player;
  295.     logfrag (self, self);
  296.     self.frags = self.frags - 2;    // extra penalty
  297.     respawn ();
  298. };
  299.  
  300. float(vector v) CheckSpawnPoint =
  301. {
  302.     return FALSE;
  303. };
  304.  
  305. /*
  306. ============
  307. SelectSpawnPoint
  308.  
  309. Returns the entity to spawn at
  310. ============
  311. */
  312. entity() SelectSpawnPoint =
  313. {
  314.     local    entity spot, thing;
  315.     local    float    pcount;
  316.  
  317. // testinfo_player_start is only found in regioned levels
  318.     spot = find (world, classname, "testplayerstart");
  319.     if (spot)
  320.         return spot;
  321.         
  322. // choose a info_player_deathmatch point
  323.     spot = lastspawn;
  324.     while (1)
  325.     {
  326.         spot = find(spot, classname, "info_player_deathmatch");
  327.         if (spot != world)
  328.         {
  329.             if (spot == lastspawn)
  330.                 return lastspawn;
  331.             pcount = 0;
  332.             thing = findradius(spot.origin, 32);
  333.             while(thing)
  334.             {
  335.                 if (thing.classname == "player")
  336.                     pcount = pcount + 1;
  337.                 thing = thing.chain;
  338.             }
  339.             if (pcount == 0)
  340.             {
  341.                 lastspawn = spot;
  342.                 return spot;
  343.             }
  344.         }
  345.     }
  346.     
  347.     spot = find (world, classname, "info_player_start");
  348.     if (!spot)
  349.         error ("PutClientInServer: no info_player_start on level");
  350.     
  351.     return spot;
  352. };
  353.  
  354. void() DecodeLevelParms;
  355. void() PlayerDie;
  356.  
  357. /*
  358. ===========
  359. ValidateUser
  360.  
  361.  
  362. ============
  363. */
  364. float(entity e) ValidateUser =
  365. {
  366. /*
  367.     local string    s;
  368.     local string    userclan;
  369.     local float    rank, rankmin, rankmax;
  370.  
  371. //
  372. // if the server has set "clan1" and "clan2", then it
  373. // is a clan match that will allow only those two clans in
  374. //
  375.     s = serverinfo("clan1");
  376.     if (s)
  377.     {
  378.         userclan = masterinfo(e,"clan");
  379.         if (s == userclan)
  380.             return true;
  381.         s = serverinfo("clan2");
  382.         if (s == userclan)
  383.             return true;
  384.         return false;
  385.     }
  386.  
  387. //
  388. // if the server has set "rankmin" and/or "rankmax" then
  389. // the users rank must be between those two values
  390. //
  391.     s = masterinfo (e, "rank");
  392.     rank = stof (s);
  393.  
  394.     s = serverinfo("rankmin");
  395.     if (s)
  396.     {
  397.         rankmin = stof (s);
  398.         if (rank < rankmin)
  399.             return false;
  400.     }
  401.     s = serverinfo("rankmax");
  402.     if (s)
  403.     {
  404.         rankmax = stof (s);
  405.         if (rankmax < rank)
  406.             return false;
  407.     }
  408.  
  409.     return true;
  410. */
  411. };
  412.  
  413.  
  414. /*
  415. ===========
  416. PutClientInServer
  417.  
  418. called each time a player enters a new level
  419. ============
  420. */
  421. void() PutClientInServer =
  422. {
  423.     local    entity spot;
  424.  
  425.     self.classname = "player";
  426.     self.health = 100;
  427.     self.takedamage = DAMAGE_AIM;
  428.     self.solid = SOLID_SLIDEBOX;
  429.     self.movetype = MOVETYPE_WALK;
  430.     self.show_hostile = 0;
  431.     self.max_health = 100;
  432.     self.flags = FL_CLIENT;
  433.     self.air_finished = time + 12;
  434.     self.dmg = 2;           // initial water damage
  435.     self.super_damage_finished = 0;
  436.     self.radsuit_finished = 0;
  437.     self.invisible_finished = 0;
  438.     self.invincible_finished = 0;
  439.     self.effects = 0;
  440.     self.invincible_time = 0;
  441. //hip
  442. //JIM
  443.     self.wetsuit_finished = 0;
  444.    //MED
  445.    self.empathy_finished = 0;
  446.    //MED
  447.    self.items2 = 0;
  448.    self.gravity = 1.0;
  449. //hip
  450.  
  451.     DecodeLevelParms ();
  452.     
  453.     W_SetCurrentAmmo ();
  454.  
  455.     self.attack_finished = time;
  456.     self.th_pain = player_pain;
  457.     self.th_die = PlayerDie;
  458.     
  459.     self.deadflag = DEAD_NO;
  460. // paustime is set by teleporters to keep the player from moving a while
  461.     self.pausetime = 0;
  462.     
  463.     spot = SelectSpawnPoint ();
  464.  
  465.     self.origin = spot.origin + '0 0 1';
  466.     self.angles = spot.angles;
  467.     self.fixangle = TRUE;        // turn this way immediately
  468.  
  469. //hip
  470.    //JIM
  471.    // Clear out velocity so you're not launched into the air
  472.    // when you respawn.
  473.    self.velocity = '0 0 0';
  474. //hip
  475.  
  476. // oh, this is a hack!
  477.     setmodel (self, "progs/playham.mdl");
  478.     modelindex_hammer = self.modelindex;
  479.  
  480.     setmodel (self, "progs/eyes.mdl");
  481.     modelindex_eyes = self.modelindex;
  482.  
  483.     setmodel (self, "progs/player.mdl");
  484.     modelindex_player = self.modelindex;
  485.  
  486.     setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
  487.     
  488.     self.view_ofs = '0 0 22';
  489.  
  490.     player_stand1 ();
  491.     
  492.     makevectors(self.angles);
  493.     spawn_tfog (self.origin + v_forward*20);
  494.  
  495.     spawn_tdeath (self.origin, self);
  496. };
  497.  
  498.  
  499. /*
  500. =============================================================================
  501.  
  502.                 QUAKED FUNCTIONS
  503.  
  504. =============================================================================
  505. */
  506.  
  507.  
  508. /*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 24)
  509. The normal starting point for a level.
  510. */
  511. void() info_player_start =
  512. {
  513. };
  514.  
  515.  
  516. /*QUAKED info_player_start2 (1 0 0) (-16 -16 -24) (16 16 24)
  517. Only used on start map for the return point from an episode.
  518. */
  519. void() info_player_start2 =
  520. {
  521. };
  522.  
  523. /*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 24)
  524. potential spawning position for deathmatch games
  525. */
  526. void() info_player_deathmatch =
  527. {
  528. };
  529.  
  530. /*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 24)
  531. potential spawning position for coop games
  532. */
  533. void() info_player_coop =
  534. {
  535. };
  536.  
  537. /*
  538. ===============================================================================
  539.  
  540. RULES
  541.  
  542. ===============================================================================
  543. */
  544.  
  545. /*
  546. go to the next level for deathmatch
  547. */
  548. void() NextLevel =
  549. {
  550.     local entity o;
  551.  
  552.     if (mapname == "start")
  553.      {
  554.          if (!cvar("registered"))
  555.          {
  556.              mapname = "e1m1";
  557.          }
  558.          else if (!(serverflags & 1))
  559.          {
  560.              mapname = "e1m1";
  561.              serverflags = serverflags | 1;
  562.          }
  563.          else if (!(serverflags & 2))
  564.          {
  565.              mapname = "e2m1";
  566.              serverflags = serverflags | 2;
  567.          }
  568.          else if (!(serverflags & 4))
  569.          {
  570.              mapname = "e3m1";
  571.              serverflags = serverflags | 4;
  572.          }
  573.          else if (!(serverflags & 8))
  574.          {
  575.              mapname = "e4m1";
  576.              serverflags = serverflags - 7;
  577.          }
  578.  
  579.          o = spawn();
  580.          o.map = mapname;
  581.      }
  582.      else
  583.      {
  584. // find a trigger changelevel
  585.         o = find(world, classname, "trigger_changelevel");
  586.         if (!o || mapname == "start")
  587.         {    // go back to same map if no trigger_changelevel
  588.             o = spawn();
  589.             o.map = mapname;
  590.         }
  591.     }
  592.  
  593.     nextmap = o.map;
  594.  
  595.     if (o.nextthink < time)
  596.     {
  597.         o.think = execute_changelevel;
  598.         o.nextthink = time + 0.1;
  599.     }
  600. };
  601.  
  602. /*
  603. ============
  604. CheckRules
  605.  
  606. Exit deathmatch games upon conditions
  607. ============
  608. */
  609. void() CheckRules =
  610. {    
  611.     if (timelimit && time >= timelimit)
  612.         NextLevel ();
  613.     
  614.     if (fraglimit && self.frags >= fraglimit)
  615.         NextLevel ();
  616. };
  617.  
  618. //============================================================================
  619.  
  620. void() PlayerDeathThink =
  621. {
  622.     local entity    old_self;
  623.     local float        forward;
  624.  
  625.     if ((self.flags & FL_ONGROUND))
  626.     {
  627.         forward = vlen (self.velocity);
  628.         forward = forward - 20;
  629.         if (forward <= 0)
  630.             self.velocity = '0 0 0';
  631.         else    
  632.             self.velocity = forward * normalize(self.velocity);
  633.     }
  634.  
  635. // wait for all buttons released
  636.     if (self.deadflag == DEAD_DEAD)
  637.     {
  638.         if (self.button2 || self.button1 || self.button0)
  639.             return;
  640.         self.deadflag = DEAD_RESPAWNABLE;
  641.         return;
  642.     }
  643.  
  644. // wait for any button down
  645.     if (!self.button2 && !self.button1 && !self.button0)
  646.         return;
  647.  
  648.     self.button0 = 0;
  649.     self.button1 = 0;
  650.     self.button2 = 0;
  651.     respawn();
  652. };
  653.  
  654.  
  655. void() PlayerJump =
  656. {
  657.     local vector start, end;
  658.  
  659.     if (self.flags & FL_WATERJUMP)
  660.         return;
  661.     
  662.     if (self.waterlevel >= 2)
  663.     {
  664. // play swiming sound
  665.         if (self.swim_flag < time)
  666.         {
  667.             self.swim_flag = time + 1;
  668.             if (random() < 0.5)
  669.                 sound (self, CHAN_BODY, "misc/water1.wav", 1, ATTN_NORM);
  670.             else
  671.                 sound (self, CHAN_BODY, "misc/water2.wav", 1, ATTN_NORM);
  672.         }
  673.  
  674.         return;
  675.     }
  676.  
  677.     if (!(self.flags & FL_ONGROUND))
  678.         return;
  679.  
  680.     if ( !(self.flags & FL_JUMPRELEASED) )
  681.         return;        // don't pogo stick
  682.  
  683.     self.flags = self.flags - (self.flags & FL_JUMPRELEASED);    
  684.     self.button2 = 0;
  685.  
  686. // player jumping sound
  687.     sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM);
  688. };
  689.  
  690.  
  691. /*
  692. ===========
  693. WaterMove
  694.  
  695. ============
  696. */
  697. .float    dmgtime;
  698.  
  699. void() WaterMove =
  700. {
  701. //dprint (ftos(self.waterlevel));
  702.     if (self.movetype == MOVETYPE_NOCLIP)
  703.         return;
  704.     if (self.health < 0)
  705.         return;
  706.  
  707.     if (self.waterlevel != 3)
  708.     {
  709.         if (self.air_finished < time)
  710.             sound (self, CHAN_VOICE, "player/gasp2.wav", 1, ATTN_NORM);
  711.         else if (self.air_finished < time + 9)
  712.             sound (self, CHAN_VOICE, "player/gasp1.wav", 1, ATTN_NORM);
  713.         self.air_finished = time + 12;
  714.         self.dmg = 2;
  715.     }
  716.     else if (self.air_finished < time)
  717.     {    // drown!
  718.         if (self.pain_finished < time)
  719.         {
  720.             self.dmg = self.dmg + 2;
  721.             if (self.dmg > 15)
  722.                 self.dmg = 10;
  723.             T_Damage (self, world, world, self.dmg);
  724.             self.pain_finished = time + 1;
  725.         }
  726.     }
  727.     
  728.     if (!self.waterlevel)
  729.     {
  730.         if (self.flags & FL_INWATER)
  731.         {    
  732.             // play leave water sound
  733.             sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM);
  734.             self.flags = self.flags - FL_INWATER;
  735.         }
  736.         return;
  737.     }
  738.  
  739.     if (self.watertype == CONTENT_LAVA)
  740.     {    // do damage
  741.         if (self.dmgtime < time)
  742.         {
  743.             if (self.radsuit_finished > time)
  744.                 self.dmgtime = time + 1;
  745.             else
  746.                 self.dmgtime = time + 0.2;
  747.  
  748.             T_Damage (self, world, world, 10*self.waterlevel);
  749.         }
  750.     }
  751.     else if (self.watertype == CONTENT_SLIME)
  752.     {    // do damage
  753.         if (self.dmgtime < time && self.radsuit_finished < time)
  754.         {
  755.             self.dmgtime = time + 1;
  756.             T_Damage (self, world, world, 4*self.waterlevel);
  757.         }
  758.     }
  759.     
  760.     if ( !(self.flags & FL_INWATER) )
  761.     {    
  762.  
  763. // player enter water sound
  764.  
  765.         if (self.watertype == CONTENT_LAVA)
  766.             sound (self, CHAN_BODY, "player/inlava.wav", 1, ATTN_NORM);
  767.         if (self.watertype == CONTENT_WATER)
  768.             sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM);
  769.         if (self.watertype == CONTENT_SLIME)
  770.             sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM);
  771.  
  772.         self.flags = self.flags + FL_INWATER;
  773.         self.dmgtime = 0;
  774.     }    
  775. };
  776.  
  777. void() CheckWaterJump =
  778. {
  779.     local vector start, end;
  780.  
  781. // check for a jump-out-of-water
  782.     makevectors (self.angles);
  783.     start = self.origin;
  784.     start_z = start_z + 8; 
  785.     v_forward_z = 0;
  786.     normalize(v_forward);
  787.     end = start + v_forward*24;
  788.     traceline (start, end, TRUE, self);
  789.     if (trace_fraction < 1)
  790.     {    // solid at waist
  791.         start_z = start_z + self.maxs_z - 8;
  792.         end = start + v_forward*24;
  793.         self.movedir = trace_plane_normal * -50;
  794.         traceline (start, end, TRUE, self);
  795.         if (trace_fraction == 1)
  796.         {    // open at eye level
  797.             self.flags = self.flags | FL_WATERJUMP;
  798.             self.velocity_z = 225;
  799.             self.flags = self.flags - (self.flags & FL_JUMPRELEASED);
  800.             self.teleport_time = time + 2;    // safety net
  801.             return;
  802.         }
  803.     }
  804. };
  805.  
  806.  
  807. /*
  808. ================
  809. PlayerPreThink
  810.  
  811. Called every frame before physics are run
  812. ================
  813. */
  814.  
  815. //hip
  816. //MED 01/17/97
  817. void(float num_bubbles) DeathBubbles;
  818. //hip
  819.  
  820. void() PlayerPreThink =
  821. {
  822.     local    float    mspeed, aspeed;
  823.     local    float    r;
  824.  
  825.     if (intermission_running)
  826.     {
  827. //hip
  828.         earthquake_prethink();
  829. //hip
  830.         IntermissionThink ();    // otherwise a button could be missed between
  831.         return;                    // the think tics
  832.     }
  833.  
  834.     if (self.view_ofs == '0 0 0')
  835.         return;        // intermission or finale
  836.  
  837. //hip
  838. //JIM
  839.    // Kill player on Edge of Oblivion
  840.    if ( ( self.origin_z < -1300 ) && (world.model == "maps/hipdm1.bsp") &&
  841.       ( self.health > 0 ) )
  842.       {
  843.       self.deathtype = "falling";
  844.  
  845.       if (self.invincible_finished >= time)
  846.          {
  847.          self.invincible_finished = 0;
  848.          self.items = self.items - (self.items & IT_INVULNERABILITY);
  849.          self.invincible_time = 0;
  850.             self.invincible_finished = 0;
  851.          self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  852.          }
  853.       T_Damage( self, self, world, self.health + 1000 );
  854.       }
  855.  
  856.     //JIM
  857. //hip
  858.  
  859.  
  860.     makevectors (self.v_angle);        // is this still used
  861.  
  862.     CheckRules ();
  863.     WaterMove ();
  864. //hip
  865. //JIM
  866.     //WETSUIT
  867.     if (self.wetsuit_finished > time)
  868.         {
  869.         if (self.waterlevel==2)
  870.             {
  871.             self.velocity = self.velocity * 1.25;
  872.             }
  873.         if (self.waterlevel==3)
  874.             {
  875.             self.velocity = self.velocity * 1.5;
  876.             }
  877.       if (self.waterlevel >= 2)
  878.          {
  879.          // play scuba sound
  880.          if (self.swim_flag < time)
  881.             {
  882.             self.swim_flag = time + 7;
  883.             sound (self, CHAN_BODY, "misc/wetsuit.wav", 1, ATTN_NORM);
  884.             }
  885.          //MED 01/17/97
  886.          else
  887.             {
  888.             if (fabs(self.swim_flag - time - 6)<0.04)
  889.                {
  890.                DeathBubbles(1);
  891.                }
  892.             else if (fabs(self.swim_flag - time - 5.5)<0.04)
  893.                {
  894.                DeathBubbles(1);
  895.                }
  896.             else if (fabs(self.swim_flag - time - 5)<0.04)
  897.                {
  898.                DeathBubbles(1);
  899.                }
  900.             }
  901.          }
  902.  
  903.     }
  904. //hip
  905.  
  906. /*
  907.     if (self.waterlevel == 2)
  908.      CheckWaterJump ();
  909. */
  910.  
  911.     if (self.deadflag >= DEAD_DEAD)
  912.     {
  913.         PlayerDeathThink ();
  914.         return;
  915.     }
  916.     
  917.     if (self.deadflag == DEAD_DYING)
  918.         return;    // dying, so do nothing
  919.  
  920.     if (self.button2)
  921.     {
  922.         PlayerJump ();
  923.     }
  924.     else
  925.         self.flags = self.flags | FL_JUMPRELEASED;
  926.  
  927. // teleporters can force a non-moving pause time    
  928.     if (time < self.pausetime)
  929.         self.velocity = '0 0 0';
  930.  
  931.      if(time > self.attack_finished && self.currentammo == 0 && self.weapon != IT_AXE && self.weapon != IT_MJOLNIR)
  932.      {
  933.          self.weapon = W_BestWeapon ();
  934.          W_SetCurrentAmmo ();
  935.      }
  936. };
  937.     
  938. /*
  939. ================
  940. CheckPowerups
  941.  
  942. Check for turning off powerups
  943. ================
  944. */
  945. void() CheckPowerups =
  946. {
  947.     if (self.health <= 0)
  948.         return;
  949.  
  950. // invisibility
  951.     if (self.invisible_finished)
  952.     {
  953. // sound and screen flash when items starts to run out
  954.         if (self.invisible_sound < time)
  955.         {
  956.             sound (self, CHAN_AUTO, "items/inv3.wav", 0.5, ATTN_IDLE);
  957.             self.invisible_sound = time + ((random() * 3) + 1);
  958.         }
  959.  
  960.  
  961.         if (self.invisible_finished < time + 3)
  962.         {
  963.             if (self.invisible_time == 1)
  964.             {
  965.                 sprint (self, PRINT_HIGH, "Ring of Shadows magic is fading\n");
  966.                 stuffcmd (self, "bf\n");
  967.                 sound (self, CHAN_AUTO, "items/inv2.wav", 1, ATTN_NORM);
  968.                 self.invisible_time = time + 1;
  969.             }
  970.             
  971.             if (self.invisible_time < time)
  972.             {
  973.                 self.invisible_time = time + 1;
  974.                 stuffcmd (self, "bf\n");
  975.             }
  976.         }
  977.  
  978.         if (self.invisible_finished < time)
  979.         {    // just stopped
  980.             self.items = self.items - IT_INVISIBILITY;
  981.             self.invisible_finished = 0;
  982.             self.invisible_time = 0;
  983.         }
  984.         
  985.     // use the eyes
  986.         self.frame = 0;
  987.         self.modelindex = modelindex_eyes;
  988.     }
  989. //hip
  990.     //MED 12/04/96 added mjolnir stuff
  991.      else if (self.weapon == IT_MJOLNIR)
  992.         self.modelindex = modelindex_hammer;   // don't use eyes
  993. //hip
  994.     else
  995.         self.modelindex = modelindex_player;    // don't use eyes or hammer
  996.  
  997. // invincibility
  998.     if (self.invincible_finished)
  999.     {
  1000. // sound and screen flash when items starts to run out
  1001.         if (self.invincible_finished < time + 3)
  1002.         {
  1003.             if (self.invincible_time == 1)
  1004.             {
  1005.                 sprint (self, PRINT_HIGH, "Protection is almost burned out\n");
  1006.                 stuffcmd (self, "bf\n");
  1007.                 sound (self, CHAN_AUTO, "items/protect2.wav", 1, ATTN_NORM);
  1008.                 self.invincible_time = time + 1;
  1009.             }
  1010.             
  1011.             if (self.invincible_time < time)
  1012.             {
  1013.                 self.invincible_time = time + 1;
  1014.                 stuffcmd (self, "bf\n");
  1015.             }
  1016.         }
  1017.         
  1018.         if (self.invincible_finished < time)
  1019.         {    // just stopped
  1020.             self.items = self.items - IT_INVULNERABILITY;
  1021.             self.invincible_time = 0;
  1022.             self.invincible_finished = 0;
  1023.         }
  1024.         if (self.invincible_finished > time)
  1025.             self.effects = self.effects | EF_DIMLIGHT;
  1026.         else
  1027.             self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  1028.     }
  1029.  
  1030. // super damage
  1031.     if (self.super_damage_finished)
  1032.     {
  1033.  
  1034. // sound and screen flash when items starts to run out
  1035.  
  1036.         if (self.super_damage_finished < time + 3)
  1037.         {
  1038.             if (self.super_time == 1)
  1039.             {
  1040.                 sprint (self, PRINT_HIGH, "Quad Damage is wearing off\n");
  1041.                 stuffcmd (self, "bf\n");
  1042.                 sound (self, CHAN_AUTO, "items/damage2.wav", 1, ATTN_NORM);
  1043.                 self.super_time = time + 1;
  1044.             }      
  1045.             
  1046.             if (self.super_time < time)
  1047.             {
  1048.                 self.super_time = time + 1;
  1049.                 stuffcmd (self, "bf\n");
  1050.             }
  1051.         }
  1052.  
  1053.         if (self.super_damage_finished < time)
  1054.         {    // just stopped
  1055.             self.items = self.items - IT_QUAD;
  1056.             self.super_damage_finished = 0;
  1057.             self.super_time = 0;
  1058.         }
  1059.         if (self.super_damage_finished > time)
  1060.             self.effects = self.effects | EF_DIMLIGHT;
  1061.         else
  1062.             self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  1063.     }    
  1064.  
  1065. // suit    
  1066.     if (self.radsuit_finished)
  1067.     {
  1068.         self.air_finished = time + 12;        // don't drown
  1069.  
  1070. // sound and screen flash when items starts to run out
  1071.         if (self.radsuit_finished < time + 3)
  1072.         {
  1073.             if (self.rad_time == 1)
  1074.             {
  1075.                 sprint (self, PRINT_HIGH, "Air supply in Biosuit expiring\n");
  1076.                 stuffcmd (self, "bf\n");
  1077.                 sound (self, CHAN_AUTO, "items/suit2.wav", 1, ATTN_NORM);
  1078.                 self.rad_time = time + 1;
  1079.             }
  1080.             
  1081.             if (self.rad_time < time)
  1082.             {
  1083.                 self.rad_time = time + 1;
  1084.                 stuffcmd (self, "bf\n");
  1085.             }
  1086.         }
  1087.  
  1088.         if (self.radsuit_finished < time)
  1089.         {    // just stopped
  1090.             self.items = self.items - IT_SUIT;
  1091.             self.rad_time = 0;
  1092.             self.radsuit_finished = 0;
  1093.         }
  1094.     }
  1095.  
  1096. //hip
  1097. //JIM
  1098. // wetsuit
  1099.     if (self.wetsuit_finished)
  1100.     {
  1101.     self.air_finished = time + 12;        // don't drown
  1102.  
  1103.     // sound and screen flash when items starts to run out
  1104.     if (self.wetsuit_finished < time + 3)
  1105.         {
  1106.             if (self.wetsuit_time == 1)
  1107.             {
  1108.                                 sprint (self, PRINT_HIGH,"Air supply in Wetsuit is running out\n");
  1109.                 stuffcmd (self, "bf\n");
  1110.                 sound (self, CHAN_AUTO, "items/suit2.wav", 1, ATTN_NORM);
  1111.                 self.wetsuit_time = time + 1;
  1112.             }
  1113.  
  1114.             if (self.wetsuit_time < time)
  1115.             {
  1116.                 self.wetsuit_time = time + 1;
  1117.                 stuffcmd (self, "bf\n");
  1118.             }
  1119.         }
  1120.  
  1121.         if (self.wetsuit_finished < time)
  1122.         {    // just stopped
  1123. //MED
  1124.          self.items2 = self.items2 - HIP_IT_WETSUIT;
  1125.             self.wetsuit_time = 0;
  1126.             self.wetsuit_finished = 0;
  1127.         }
  1128.     }
  1129.  
  1130. //MED
  1131. // empathy shields
  1132.    if (self.empathy_finished)
  1133.     {
  1134.       // sound and screen flash when items starts to run out
  1135.       if (self.empathy_finished < time + 3)
  1136.         {
  1137.          if (self.empathy_time == 1)
  1138.             {
  1139.             sprint (self, PRINT_HIGH,"Empathy Shields are running out\n");
  1140.                 stuffcmd (self, "bf\n");
  1141.                 sound (self, CHAN_AUTO, "items/suit2.wav", 1, ATTN_NORM);
  1142.             self.empathy_time = time + 1;
  1143.             }
  1144.  
  1145.          if (self.empathy_time < time)
  1146.             {
  1147.             self.empathy_time = time + 1;
  1148.                 stuffcmd (self, "bf\n");
  1149.             }
  1150.         }
  1151.  
  1152.       if (self.empathy_finished < time)
  1153.         {    // just stopped
  1154. //MED
  1155.          self.items2 = self.items2 - HIP_IT_EMPATHY_SHIELDS;
  1156.          self.empathy_time = 0;
  1157.          self.empathy_finished = 0;
  1158.         }
  1159. //MED
  1160.       if (self.empathy_finished > time)
  1161.             self.effects = self.effects | EF_DIMLIGHT;
  1162.         else
  1163.             self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  1164.    }
  1165. //hip    
  1166. };
  1167.  
  1168.  
  1169. /*
  1170. ================
  1171. PlayerPostThink
  1172.  
  1173. Called every frame after physics are run
  1174. ================
  1175. */
  1176. void() PlayerPostThink =
  1177. {
  1178.     local    float    mspeed, aspeed;
  1179.     local    float    r;
  1180.  
  1181. //dprint ("post think\n");
  1182.     if (self.view_ofs == '0 0 0')
  1183. //hip
  1184.       {
  1185.           earthquake_postthink();
  1186. //hip
  1187.         return;        // intermission or finale
  1188. //hip
  1189.     }
  1190.     //JIM
  1191.     //WETSUIT
  1192.     if (self.wetsuit_finished > time)
  1193.         {
  1194.         if (self.waterlevel==2)
  1195.             {
  1196.             self.velocity = self.velocity * 0.8;
  1197.             }
  1198.         if (self.waterlevel==3)
  1199.             {
  1200.             self.velocity = self.velocity * 0.66;
  1201.             }
  1202.       }
  1203.  
  1204.     //JIM
  1205. //   if (!deathmatch)
  1206. //      {
  1207.       earthquake_postthink();
  1208. //      }
  1209. //hip
  1210.     if (self.deadflag)
  1211.         return;
  1212.  
  1213. // check to see if player landed and play landing sound    
  1214.     if ((self.jump_flag < -300) && (self.flags & FL_ONGROUND) )
  1215.     {
  1216.         if (self.watertype == CONTENT_WATER)
  1217.             sound (self, CHAN_BODY, "player/h2ojump.wav", 1, ATTN_NORM);
  1218.         else if (self.jump_flag < -650)
  1219.         {
  1220.             T_Damage (self, world, world, 5); 
  1221.             sound (self, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
  1222.             self.deathtype = "falling";
  1223.         }
  1224.         else
  1225.             sound (self, CHAN_VOICE, "player/land.wav", 1, ATTN_NORM);
  1226.     }
  1227.  
  1228.     self.jump_flag = self.velocity_z;
  1229.  
  1230.     CheckPowerups ();
  1231.  
  1232.     W_WeaponFrame ();
  1233.  
  1234. };
  1235.  
  1236.  
  1237. /*
  1238. ===========
  1239. ClientConnect
  1240.  
  1241. called when a player connects to a server
  1242. ============
  1243. */
  1244. void() ClientConnect =
  1245. {
  1246.     bprint (PRINT_HIGH, self.netname);
  1247.     bprint (PRINT_HIGH, " entered the game\n");
  1248.     
  1249. // a client connecting during an intermission can cause problems
  1250.     if (intermission_running)
  1251.         GotoNextMap ();
  1252. };
  1253.  
  1254.  
  1255. /*
  1256. ===========
  1257. ClientDisconnect
  1258.  
  1259. called when a player disconnects from a server
  1260. ============
  1261. */
  1262. void() ClientDisconnect =
  1263. {
  1264.     // let everyone else know
  1265.     bprint (PRINT_HIGH, self.netname);
  1266.     bprint (PRINT_HIGH, " left the game with ");
  1267.     bprint (PRINT_HIGH, ftos(self.frags));
  1268.     bprint (PRINT_HIGH, " frags\n");
  1269.     sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE);
  1270.     set_suicide_frame ();
  1271. };
  1272.  
  1273. /*
  1274. ===========
  1275. ClientObituary
  1276.  
  1277. called when a player dies
  1278. ============
  1279. */
  1280. void(entity targ, entity attacker) ClientObituary =
  1281. {
  1282.     local    float rnum;
  1283.     local    string deathstring, deathstring2;
  1284.     local    string s;
  1285.     local    float    attackerteam, targteam;
  1286.  
  1287.     rnum = random();
  1288.  
  1289.     if (targ.classname == "player")
  1290.     {
  1291.         if (attacker.classname == "teledeath")
  1292.         {
  1293.             bprint (PRINT_MEDIUM,targ.netname);
  1294.             bprint (PRINT_MEDIUM," was fuckin' telefragged by ");
  1295.             bprint (PRINT_MEDIUM,attacker.owner.netname);
  1296.             bprint (PRINT_MEDIUM,"\n");
  1297.  
  1298.             attacker.owner.frags = attacker.owner.frags + 1;
  1299.             return;
  1300.         }
  1301.  
  1302.         if (attacker.classname == "teledeath2")
  1303.         {
  1304.             bprint (PRINT_MEDIUM,"Satan's power deflects ");
  1305.             bprint (PRINT_MEDIUM,targ.netname);
  1306.             bprint (PRINT_MEDIUM,"'s telefrag\n");
  1307.  
  1308.             targ.frags = targ.frags - 1;
  1309.             logfrag (targ, targ);
  1310.             return;
  1311.         }
  1312.  
  1313.         if (attacker.classname == "player")
  1314.         {
  1315. //ZOID 12-13-96: self.team doesn't work in QW.  Use keys
  1316.             s = infokey(attacker, "bottomcolor");
  1317.             attackerteam = stof(s);
  1318.             s = infokey(targ, "bottomcolor");
  1319.             targteam = stof(s);
  1320.  
  1321.             if (targ == attacker)
  1322.             {
  1323.                 // killed self
  1324.                 logfrag (attacker, attacker);
  1325.                 attacker.frags = attacker.frags - 1;
  1326.                 bprint (PRINT_MEDIUM,targ.netname);
  1327.                 
  1328.                 if (targ.weapon == 64 && targ.waterlevel > 1)
  1329.                 {
  1330.                     bprint (PRINT_MEDIUM," whizzes in the swimming pool\n");
  1331.                     return;
  1332.                 }
  1333.                 if (targ.weapon == 16)
  1334.                     bprint (PRINT_MEDIUM," couldn't fit the pin back in\n");
  1335.                 else if (rnum)
  1336.                     bprint (PRINT_MEDIUM," goes suicidal\n");
  1337.                 else
  1338.                     bprint (PRINT_MEDIUM," cleans his gun for the last time\n");
  1339.                 return;
  1340.             }
  1341.             else if ( (teamplay == 2) && (targteam == attackerteam) )
  1342.              {
  1343.                  if (rnum < 0.25)
  1344.                      deathstring = " just assraped a teammate\n";
  1345.                  else if (rnum < 0.50)
  1346.                      deathstring = " is a teammate killer!!!\n";
  1347.                  else if (rnum < 0.75)
  1348.                      deathstring = " gets a frag for the other team\n";
  1349.                  else
  1350.                      deathstring = " loses another friend\n";
  1351.                  bprint (PRINT_MEDIUM, attacker.netname);
  1352.                  bprint (PRINT_MEDIUM, deathstring);
  1353.                  attacker.frags = attacker.frags - 1;
  1354.                 //ZOID 12-13-96:  killing a teammate logs as suicide
  1355.                 logfrag (attacker, attacker);
  1356.                   return;
  1357.               }
  1358.             else
  1359.             {
  1360.                 logfrag (attacker, targ);
  1361.                 attacker.frags = attacker.frags + 1;
  1362. //hip
  1363. //MED 01/19/97
  1364.             if (empathyused == 1)
  1365.                {
  1366.                bprint (PRINT_MEDIUM,targ.netname);
  1367.                if (random()<0.5)
  1368.                   bprint (PRINT_MEDIUM, " shares in ");
  1369.                else
  1370.                   bprint (PRINT_MEDIUM, " feels ");
  1371.                bprint (PRINT_MEDIUM, attacker.netname);
  1372.                bprint (PRINT_MEDIUM, "'s pain\n");
  1373.                return;
  1374.                }
  1375.  
  1376. //MED 11/18/96
  1377.             if (targ.dmg_inflictor.classname == "proximity_grenade")
  1378.                {
  1379.                bprint (PRINT_MEDIUM,targ.netname);
  1380.                if (random()<0.5) {
  1381.                    bprint (PRINT_MEDIUM, " did the rhumba with ");
  1382.                    bprint (PRINT_MEDIUM, attacker.netname);
  1383.                    bprint (PRINT_MEDIUM, "'s bomb-a\n");
  1384.            }
  1385.                else
  1386.            {
  1387.                   bprint (PRINT_MEDIUM, " has shrapnel from ");
  1388.             bprint (PRINT_MEDIUM, attacker.netname);
  1389.             bprint (PRINT_MEDIUM, "'s bomb in his ass\n");
  1390.              }
  1391.                return;
  1392.                }
  1393. //hip
  1394.                 rnum = attacker.weapon;
  1395.                 if (rnum == IT_AXE)
  1396.                 {
  1397.                     deathstring = " was ax-murdered by ";
  1398.                     deathstring2 = "\n";
  1399.                 }
  1400.                 if (rnum == IT_SHOTGUN)
  1401.                 {
  1402.                     deathstring = " sucked on ";
  1403.                     deathstring2 = "'s stick\n";
  1404.                 }
  1405.                 if (rnum == IT_SUPER_SHOTGUN)
  1406.                 {
  1407.                     deathstring = " ate 2 loads of ";
  1408.                     deathstring2 = "'s buckshot\n";
  1409.                 }
  1410.                 if (rnum == IT_NAILGUN)
  1411.                 {
  1412.                     deathstring = " was nailed by nine inches of ";
  1413.                     deathstring2 = "\n";
  1414.                 }
  1415.                 if (rnum == IT_SUPER_NAILGUN)
  1416.                 {
  1417.                     deathstring = " was devirginized by ";
  1418.                     deathstring2 = "'s nails\n";
  1419.                 }
  1420.                 if (rnum == IT_GRENADE_LAUNCHER)
  1421.                 {
  1422.                     deathstring = " cuddles with ";
  1423.                     deathstring2 = "'s pineapple\n";
  1424.                     if (targ.health < -40)
  1425.                     {
  1426.                         deathstring = " was gimped by ";
  1427.                         deathstring2 = "'s grenade\n";
  1428.                     }
  1429.                 }
  1430.                 if (rnum == IT_ROCKET_LAUNCHER)
  1431.                 {
  1432.                     deathstring = " flies ";
  1433.                     deathstring2 = "'s friendly skies\n";
  1434.                     if (targ.health < -40)
  1435.                     {
  1436.                         deathstring = " was gimped by ";
  1437.                         deathstring2 = "'s rocket\n" ;
  1438.                     }
  1439.                 }
  1440.                 if (rnum == IT_LIGHTNING)
  1441.                 {
  1442.                     deathstring = " accepts ";
  1443.                     if (attacker.waterlevel > 1)
  1444.                         deathstring2 = "'s creamy white discharge\n";
  1445.                     else
  1446.                         deathstring2 = "'s thick shaft\n";
  1447.                 }
  1448. //MED
  1449.             if (rnum == IT_LASER_CANNON)
  1450.                 {
  1451.                if (random()<0.5)
  1452.                   {
  1453.                   deathstring = " was toasted by ";
  1454.                   }
  1455.                else
  1456.                   {
  1457.                   deathstring = " was radiated by ";
  1458.                   }
  1459.                deathstring2 = "'s laser\n";
  1460.                 }
  1461. //MED
  1462.             if (rnum == IT_MJOLNIR)
  1463.                 {
  1464.                deathstring = " was slammed by ";
  1465.                deathstring2 = "'s hammer\n";
  1466.                 }
  1467.  
  1468.                 bprint (PRINT_MEDIUM,targ.netname);
  1469.                 bprint (PRINT_MEDIUM,deathstring);
  1470.                 bprint (PRINT_MEDIUM,attacker.netname);
  1471.                 bprint (PRINT_MEDIUM,deathstring2);
  1472.             }
  1473.             return;
  1474.         }
  1475.         else
  1476.         {
  1477.             logfrag (targ, targ);
  1478.             targ.frags = targ.frags - 1;        // killed self
  1479.             rnum = targ.watertype;
  1480.  
  1481.             bprint (PRINT_MEDIUM,targ.netname);
  1482.             if (rnum == -3)
  1483.             {
  1484.                 if (random() < 0.5)
  1485.                     bprint (PRINT_MEDIUM," sleeps with the fishes\n");
  1486.                 else
  1487.                     bprint (PRINT_MEDIUM," sucks it down\n");
  1488.                 return;
  1489.             }
  1490.             else if (rnum == -4)
  1491.             {
  1492.                 if (random() < 0.5)
  1493.                     bprint (PRINT_MEDIUM," gulped a load of slime\n");
  1494.                 else
  1495.                     bprint (PRINT_MEDIUM," can't exist on slime alone\n");
  1496.                 return;
  1497.             }
  1498.             else if (rnum == -5)
  1499.             {
  1500.                 if (targ.health < -15)
  1501.                 {
  1502.                     bprint (PRINT_MEDIUM," burst into flames\n");
  1503.                     return;
  1504.                 }
  1505.                 if (random() < 0.5)
  1506.                     bprint (PRINT_MEDIUM," turned into hot slag\n");
  1507.                 else
  1508.                     bprint (PRINT_MEDIUM," visits the Volcano God\n");
  1509.                 return;
  1510.             }
  1511.  
  1512.             if (attacker.flags & FL_MONSTER)
  1513.             {
  1514.                 if (attacker.classname == "monster_army")
  1515.                     bprint (PRINT_MEDIUM," was shot by a Grunt\n");
  1516.                 if (attacker.classname == "monster_demon1")
  1517.                     bprint (PRINT_MEDIUM," was eviscerated by a Fiend\n");
  1518.                 if (attacker.classname == "monster_dog")
  1519.                     bprint (PRINT_MEDIUM," was mauled by a Rottweiler\n");
  1520.                 if (attacker.classname == "monster_dragon")
  1521.                     bprint (PRINT_MEDIUM," was fried by a Dragon\n");
  1522.                 if (attacker.classname == "monster_enforcer")
  1523.                     bprint (PRINT_MEDIUM," was blasted by an Enforcer\n");
  1524.                 if (attacker.classname == "monster_fish")
  1525.                     bprint (PRINT_MEDIUM," was fed to the Rotfish\n");
  1526.                 if (attacker.classname == "monster_hell_knight")
  1527.                     bprint (PRINT_MEDIUM," was slain by a Death Knight\n");
  1528.                 if (attacker.classname == "monster_knight")
  1529.                     bprint (PRINT_MEDIUM," was slashed by a Knight\n");
  1530.                 if (attacker.classname == "monster_ogre")
  1531.                     bprint (PRINT_MEDIUM," was destroyed by an Ogre\n");
  1532.                 if (attacker.classname == "monster_oldone")
  1533.                     bprint (PRINT_MEDIUM," became one with Shub-Niggurath\n");
  1534.                 if (attacker.classname == "monster_shalrath")
  1535.                     bprint (PRINT_MEDIUM," was exploded by a Vore\n");
  1536.                 if (attacker.classname == "monster_shambler")
  1537.                     bprint (PRINT_MEDIUM," was smashed by a Shambler\n");
  1538.                 if (attacker.classname == "monster_tarbaby")
  1539.                     bprint (PRINT_MEDIUM," was slimed by a Spawn\n");
  1540.                 if (attacker.classname == "monster_vomit")
  1541.                     bprint (PRINT_MEDIUM," was vomited on by a Vomitus\n");
  1542.                 if (attacker.classname == "monster_wizard")
  1543.                     bprint (PRINT_MEDIUM," was scragged by a Scrag\n");
  1544.                 if (attacker.classname == "monster_zombie")
  1545.                     bprint (PRINT_MEDIUM," joins the Zombies\n");
  1546. //hip
  1547. //MED
  1548.             if (attacker.classname == "monster_gremlin")
  1549.                bprint (PRINT_MEDIUM," was outsmarted by a Gremlin\n");
  1550. //MED
  1551.             if (attacker.classname == "monster_scourge")
  1552.                bprint (PRINT_MEDIUM," was stung by a Centroid\n");
  1553. //MED
  1554.             if (attacker.classname == "monster_armagon")
  1555.                bprint (PRINT_MEDIUM," was outgunned by Armagon\n");
  1556. //hip
  1557.  
  1558.                 return;
  1559.             }
  1560.             if (attacker.classname == "explo_box")
  1561.             {
  1562.                 bprint (PRINT_MEDIUM," go boom\n");
  1563.                 return;
  1564.             }
  1565.             if (attacker.solid == SOLID_BSP && attacker != world)
  1566.             {    
  1567.                 bprint (PRINT_MEDIUM," go squish\n");
  1568.                 return;
  1569.             }
  1570.             if (targ.deathtype == "falling")
  1571.             {
  1572.                 bprint (PRINT_MEDIUM," forgot to use his pixie dust\n");
  1573.                 return;
  1574.             }
  1575.             if (attacker.classname == "trap_shooter" || attacker.classname == "trap_spikeshooter")
  1576.             {
  1577.                 bprint (PRINT_MEDIUM," took a nail in the ass\n");
  1578.                 return;
  1579.             }
  1580.             if (attacker.classname == "fireball")
  1581.             {
  1582.                 bprint (PRINT_MEDIUM," tries to catch a lavaball\n");
  1583.                 return;
  1584.             }
  1585.             if (attacker.classname == "trigger_changelevel")
  1586.             {
  1587.                 bprint (PRINT_MEDIUM," tried to leave\n");
  1588.                 return;
  1589.             }
  1590.  
  1591.             bprint (PRINT_MEDIUM," dies mysteriously\n");
  1592.         }
  1593.     }
  1594. };
  1595.